package com.fjbdxk.beidou;

import com.fjbdxk.beidou.core.AbstractBeiDouMessage;
import com.fjbdxk.beidou.core.ByteUtils;
import com.fjbdxk.beidou.msg.BDFKIMessage;
import com.fjbdxk.beidou.msg.CCTCQMessage;
import com.fjbdxk.beidou.net.SocketBeiDouNet;


import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.ArrayList;
import java.util.List;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.SimpleFormatter;
import java.util.Arrays;


public class SendExample {
    private static final Logger LOGGER = Logger.getLogger(SendExample.class.getName());
    // 初始化日志记录器
    static {
        try {
            FileHandler fileHandler = new FileHandler("D:\\工作日期\\20240514\\log\\sendexample.log");
            LOGGER.addHandler(fileHandler);
            SimpleFormatter formatter = new SimpleFormatter();
            fileHandler.setFormatter(formatter);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        SocketBeiDouNet socketBeiDouNet = new SocketBeiDouNet();

        socketBeiDouNet.open();
        //sendOnce(socketBeiDouNet);
        sendFile(socketBeiDouNet);
    }
    public static void sendOnce(SocketBeiDouNet socketBeiDouNet) {
        CCTCQMessage cctcqMessage = new CCTCQMessage(15950114, "41424344");
        cctcqMessage.setEncodeType(2);
        LOGGER.info("Sending single message: " + cctcqMessage.getMsg());
        AbstractBeiDouMessage abstractBeiDouMessage = socketBeiDouNet.sendMessage(cctcqMessage);
        if (abstractBeiDouMessage instanceof BDFKIMessage) {
            BDFKIMessage bdfkiMessage = (BDFKIMessage) abstractBeiDouMessage;
            if ("Y".equals(bdfkiMessage.getResult())) {
                LOGGER.info("Transmission successful");
            } else {
                LOGGER.warning("Transmission failed. Reason: " + bdfkiMessage.getFailResult());
            }
        } else {
            LOGGER.warning("Unknown error message");
        }
    }
    public static void sendFile(SocketBeiDouNet socketBeiDouNet) throws InterruptedException {
        try {
            File file = new File("D:\\工作日期\\20240514\\1.csv");
            //List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
            Path filePath = Paths.get(file.toURI());
            byte[] fileContentBytes = Files.readAllBytes(filePath);
            List<List<byte[]>> slices = sliceByteArray(fileContentBytes, 100);
            //List<List<String>> slices = sliceList(lines, 500);
            String num = "0001";
            String fileName = "1.csv";
            String size = Integer.toString(slices.size());
            String content = String.join("_", "1", num, size, URLEncoder.encode(fileName));
            //String content ="PLC状态,35,环境温度,0风速,6000功率";
            CCTCQMessage fileNameMsg = new CCTCQMessage(15950114, content);
            fileNameMsg.setEncodeType(2);
            LOGGER.info("Sending file name message: " + fileNameMsg.getMsg());
            BDFKIMessage res1 = (BDFKIMessage) socketBeiDouNet.sendMessage(fileNameMsg);
            LOGGER.info(res1 == null ? "N" : (res1.getResult() + ":" + res1.getFailResult()));

            Thread.sleep(5000);
            String data ="PLC状态,35,环境温度,0风速,6000功率,6000转矩,600发电机转速,1000叶轮转速,1200风向,1800桨距角,50发电量,3000";
            CCTCQMessage dataMsg = new CCTCQMessage(15950114, data);
            dataMsg.setEncodeType(2);
            LOGGER.info("Sending file name message: " + dataMsg.getMsg());
            BDFKIMessage res2 = (BDFKIMessage) socketBeiDouNet.sendMessage(dataMsg);
            LOGGER.info(res2 == null ? "N" : (res2.getResult() + ":" + res2.getFailResult()));

            for (List<byte[]> slice : slices) {
                Thread.sleep(60000);
                for (byte[] lineBytes : slice) {
                    String line = new String(lineBytes, StandardCharsets.UTF_8);
                    String[] parts = line.split(",");
                    if (parts.length == 2) {
                        String pointName = parts[0].trim();
                        String pointValueStr = parts[1].trim();
                        //String[] range = parts[2].trim().split("\\(|,|\\)");
                        switch (pointName) {
                            case "PLC状态":
                                byte[] pointValueBytes = pointValueStr.getBytes(StandardCharsets.UTF_8);
                                validateAndSendData(socketBeiDouNet, num, pointName, pointValueBytes, 1.0, 0, 70);
                                break;
                            case "环境温度":
                                byte[] pointValueBytesEnv = pointValueStr.getBytes(StandardCharsets.UTF_8);
                                validateAndSendData(socketBeiDouNet, num, pointName, pointValueBytesEnv, 1.0, -50, 50);
                                break;
                            case "风速":
                                byte[] pointValueBytesWind = pointValueStr.getBytes(StandardCharsets.UTF_8);
                                validateAndSendData(socketBeiDouNet, num, pointName, pointValueBytesWind, 0.01,0, 10000);
                                break;
                            case "功率":
                                byte[] pointValueBytesPower = pointValueStr.getBytes(StandardCharsets.UTF_8);
                                validateAndSendData(socketBeiDouNet, num, pointName, pointValueBytesPower, 0.01,0, 10000);
                                break;
                            case "转矩":
                                byte[] pointValueBytesTorque = pointValueStr.getBytes(StandardCharsets.UTF_8);
                                validateAndSendData(socketBeiDouNet, num, pointName, pointValueBytesTorque, 0.1, 0, 10000);
                                break;
                            case "发电机转速":
                                byte[] pointValueBytesGeneratorSpeed = pointValueStr.getBytes(StandardCharsets.UTF_8);
                                validateAndSendData(socketBeiDouNet, num, pointName, pointValueBytesGeneratorSpeed, 1.0, 0, 2000);
                                break;
                            case "叶轮转速":
                                byte[] pointValueBytesImpellerSpeed = pointValueStr.getBytes(StandardCharsets.UTF_8);
                                validateAndSendData(socketBeiDouNet, num, pointName, pointValueBytesImpellerSpeed, 0.01, 0, 2000);
                                break;
                            case "风向":
                                byte[] pointValueBytesWindDirection = pointValueStr.getBytes(StandardCharsets.UTF_8);
                                validateAndSendData(socketBeiDouNet, num, pointName, pointValueBytesWindDirection, 0.1, 0, 3600);
                                break;
                            case "桨距角":
                                byte[] pointValueBytesBladeAngle = pointValueStr.getBytes(StandardCharsets.UTF_8);
                                validateAndSendData(socketBeiDouNet, num, pointName, pointValueBytesBladeAngle, 0.1, -100, 1000);
                                break;
                            case "发电量":
                                byte[] pointValueBytesPowerGeneration = pointValueStr.getBytes(StandardCharsets.UTF_8);
                                validateAndSendData(socketBeiDouNet, num, pointName, pointValueBytesPowerGeneration, 1.0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
                                break;
                            default:
                                LOGGER.warning("Unsupported point: " + pointName);
                                break;
                        }
                    }
                }
            }

        } catch (IOException e) {
            LOGGER.severe("An error occurred: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private static List<List<byte[]>> sliceByteArray(byte[] originalArray, int sliceSize) {
        List<List<byte[]>> result = new ArrayList<>();
        for (int i = 0; i < originalArray.length; i += sliceSize) {
            int end = Math.min(originalArray.length, i + sliceSize);
            byte[] slice = Arrays.copyOfRange(originalArray, i, end);
            //result.add(slice);
            result.add(Arrays.asList(slice)); // 将包含字节数组的列表添加到结果列表中
        }
        return result;
    }

    private static String validateAndSendData(String pointName, String pointValueStr, double coefficient, double lowerBound, double upperBound) {
        //String pointValueStr = new String(pointValueBytes, StandardCharsets.UTF_8);
        try {
            double value = Double.parseDouble(pointValueStr) * coefficient;  // 根据系数转换测点值
            LOGGER.info("Range for " + pointName + ": " + lowerBound + " to " + upperBound);
            if (value < lowerBound || value > upperBound) {
                LOGGER.warning("Value for " + pointName + " out of range: " + pointValueStr);
                pointValueStr = "error";
            }
        } catch (NumberFormatException e) {
            LOGGER.warning("Invalid value for " + pointName + ": " + pointValueStr);
            pointValueStr = "error";
        }
        return pointValueStr;

    }

    private static void validateAndSendData(SocketBeiDouNet socketBeiDouNet, String num, String pointName, byte[] pointValueBytes, double coefficient, double lowerBound, double upperBound) {
        String pointValueStr = new String(pointValueBytes, StandardCharsets.UTF_8);
        try {
            double value = Double.parseDouble(pointValueStr) * coefficient;  // 根据系数转换测点值
            LOGGER.info("Range for " + pointName + ": " + lowerBound + " to " + upperBound);
            if (value < lowerBound || value > upperBound) {
                LOGGER.warning("Value for " + pointName + " out of range: " + pointValueStr);
                pointValueStr = "error";
            }
        } catch (NumberFormatException e) {
            LOGGER.warning("Invalid value for " + pointName + ": " + pointValueStr);
            pointValueStr = "error";
        }
        String fileContent = String.join("_",
                "2",
                num,
                pointName,
                pointValueStr);
        CCTCQMessage msg = new CCTCQMessage(15950114, fileContent);
        msg.setEncodeType(2);
        LOGGER.info("Sending file content message: " + msg.getMsg());
        BDFKIMessage res = (BDFKIMessage) socketBeiDouNet.sendMessage(msg);
        LOGGER.info(res == null ? "N" : (res.getResult() + ":" + res.getFailResult()));
    }
    public static void parse() {
        byte[] bytes = ByteUtils.hexStr2bytes("325F303030315F345F453442383830453442413843453442383839453539423942453442413934453538354144453442383833453538354142453442393944453538443831453442383830453442413843453442383839453539423942453442413934453538354144453442383833453538354142453442393944453538443831");
        LOGGER.info(new String(bytes));
        byte[] bytes1 = ByteUtils.hexStr2bytes("325F303030315F315F5B42403137656434306530");
        LOGGER.info(new String(bytes1));
        byte[] bytes2 = ByteUtils.hexStr2bytes("325F303030315F325F5B42403530363735363930");
        LOGGER.info(new String(bytes2));
        byte[] bytes3 = ByteUtils.hexStr2bytes("325F303030315F335F5B42403331623764656130");
        LOGGER.info(new String(bytes3));
        byte[] bytes4 = ByteUtils.hexStr2bytes("325F303030315F345F5B42403361633432393136");
        LOGGER.info(new String(bytes4));
        byte[] bytes5 = ByteUtils.hexStr2bytes("325F303030315F355F5B42403437643338346565");
        LOGGER.info(new String(bytes5));
    }
}